import Koa from 'koa'
import body from 'koa-body'
import json from 'koa-json'
import globalException from './GlobalExce'
import Router from 'koa-router'
import path from 'path'
import fs from 'fs'

class AllCtrlRouterLoader {
  app!: Koa
  static allCtrlRouterLoader: AllCtrlRouterLoader = new AllCtrlRouterLoader()

  init(app: Koa) {
    this.app = app
    this.loadMiddleware()
    this.storeRootRouterToCtx() //保存根路由
    this.loadAllCtrlRouterWrapper() //加载控制器路由
    this.listen()
  }

  loadMiddleware() {
    this.app.use(json())
    this.app.use(body())
    this.app.use(globalException)
  }

  storeRootRouterToCtx() {
    const rootRouter = new Router()
    rootRouter.prefix('/dang')
    this.app.context.rootRouter = rootRouter
    this.app.use(rootRouter.routes())
  }

  //1、加载所有路由文件数组
  getFiles(dir: string) {
    const allFiles = fs.readdirSync(dir)
    // console.log('all files:', allFiles)
    return allFiles
  }
  //2、加载所有路由文件绝对路径数组
  getAbsoluteFilePath(): string[] {
    const dir = path.join(process.cwd(), '/src/controller')
    const allFiles = this.getFiles(dir)
    const allFullFilePaths: string[] = []
    for (const file of allFiles) {
      if (this.isCtrlFile(file)) {
        const fullFilePath = dir + '/' + file
        allFullFilePaths.push(fullFilePath)
      }
    }
    return allFullFilePaths
  }

  isCtrlFile(file: string): boolean {
    const extName = path.extname(file)
    const fileName = path.basename(file, extName)
    console.log('file', fileName, extName)
    return extName === '.ts' && fileName.includes('Controller')
  }
  loadAllCtrlRouterWrapper() {
    //3.1 调用获取绝对路径数组方法
    const allFullFilePaths = this.getAbsoluteFilePath()
    //3.2 调用加载所有一级路由到二级路由方法

    this.loadAllRouter(allFullFilePaths)
  }

  loadAllRouter(allFullFilePaths: string[]) {
    console.log('111', allFullFilePaths)
    for (const fullFilePath of allFullFilePaths) {
      require(fullFilePath)
    }
  }

  listen() {
    this.app.listen(3002)
    console.log('server is running on port 3002')
  }
}

export const { allCtrlRouterLoader } = AllCtrlRouterLoader
